#include <stdio.h>
#include <stdlib.h>


void match(unsigned char a, unsigned char b, int *counter)
{
    unsigned char c = a ^ b;
    int idx;

    for (idx = 0; idx < 256; idx++) {
        if (idx == (int)c) {
            printf ("STATUS: matching index = %d %d\n", idx, counter[idx]);
            counter[idx] += 1;
            idx = 256;
        }
    }
}

int main (int argc, char *argv[])
{
    FILE *fi, *fo;
    int sz, cnt;
    int a, b;
    unsigned int max_cnt;
    unsigned int *counter; 
    unsigned int offset;

    if ((fi = fopen(argv[1], "rb")) == NULL) {
        printf("ERROR: unable to open input ciphertext %s\n", argv[1]);
        return EXIT_FAILURE;
    }

    fseek(fi, 0L, SEEK_END);
    sz = ftell(fi);
    printf("STATUS: size of ciphertext %d\n", sz);
    fseek(fi, 0L, SEEK_SET);

    if ((fo = fopen(argv[1], "rb")) == NULL) {
        printf("ERROR: unable to open input ciphertext %s\n", argv[1]);
        return EXIT_FAILURE;
    }

    counter = calloc(256, sizeof(unsigned int));
    if (counter == NULL) {
        printf("ERROR: unable to allocate memory for the counter\n");
        return EXIT_FAILURE;
    }


    for (offset = 1; offset < 7; offset++) {
        fseek(fo, offset, SEEK_SET);
        printf("STATUS: Trying for offset = %d\n", offset);
        for (cnt = 0; cnt < sz; cnt++) {
            a = fgetc(fi);
            //printf("STATUS: outer ciphertext = %c\n", a);
            if ((b = fgetc(fo)) != EOF) {
                //printf("STATUS: inner ciphertext = %c\n", b);
                match ((unsigned char)a, (unsigned char)b, counter);
            } else {
                rewind(fo);
                b = fgetc(fo);
                //printf("STATUS: inner ciphertext = %c\n", b);
                match ((unsigned char)a, (unsigned char)b, counter);
            }
        }
        rewind(fi);
        rewind(fo);
    }

    max_cnt = 0;
    max_idx = 0;
    for (cnt = 0; cnt < 256; cnt++) {
        printf("STATUS: counter[%d] = %d\n", cnt, counter[cnt]);
        if (max_cnt < counter[cnt]) {
            max_cnt = cnt;
        }
    }

    printf("RESULT: max_cnt = %d\n", max_cnt);

    return EXIT_SUCCESS;
}
